<template>
  <a-card :bordered="false">
    <a-row>
      <a-col>
        <a-form-model layout="inline" :model="model" @submit="handleSubmit" @submit.native.prevent>
          <a-form-model-item>
            <a-input v-model="model.esUrl" placeholder="url"> </a-input>
          </a-form-model-item>
          <a-form-model-item>
            <a-input v-model="model.index" placeholder="index_name"> </a-input>
          </a-form-model-item>
          <a-form-model-item>
            <a-button type="primary" html-type="submit" :disabled="model.user === '' || model.password === ''">
              连接
            </a-button>
          </a-form-model-item>
        </a-form-model>
      </a-col>
      <a-col>
        <j-vxe-table
          ref="jvxetable"
          toolbar
          :toolbarConfig="toolbarConfig"
          row-number
          row-selection
          keep-source
          :height="340"
          :loading="loading"
          :columns="columns"
          :dataSource="dataSource"
          :pagination="pagination"
          @save="handleTableSave"
          @remove="handleTableRemove"
          @edit-closed="handleEditClosed"
          @pageChange="handlePageChange"
          @selectRowChange="handleSelectRowChange"
        >
          <template v-slot:toolbarSuffix>
            <a-button @click="handleAdd">添加</a-button>
            <a-button>删除</a-button>
            <a-button>刷新</a-button>
            <a-popover trigger="click" placement="bottomLeft">
              <template slot="content">
                <div style="width: 200px">
                  <a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
                    全选
                  </a-checkbox>
                  <a-button type="link" @click="handleAllocationpSave">保存</a-button>
                  <a-divider />
                  <a-checkbox-group v-model="checkedList" @change="handleAllocationp">
                    <a-row>
                      <a-col :span="24" v-for="(column, index) in columns" :key="index">
                        <a-checkbox :value="column.key"> {{ column.title }} </a-checkbox>
                      </a-col>
                    </a-row>
                  </a-checkbox-group>
                </div>
              </template>
              <a-button>配置列</a-button>
            </a-popover>
          </template>
        </j-vxe-table>
      </a-col>
    </a-row>
    <dataBrowserModal ref="modalForm"></dataBrowserModal>
    <!--
        【即时保存大体思路】：
        1. JVxeTable 上必须加 keep-source 属性
        2. 监听 edit-closed事件，这个事件是在编辑完成后触发
        3. 在这个事件里面判断数据是否更改，如果更改了就调用接口进行保存操作
      -->
  </a-card>
</template>
  
  <script>
import VJsoneditor from 'v-jsoneditor'
import vueJsonEditor from 'vue-json-editor'
import { getAction, postAction, putAction } from '@api/manage'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import dataBrowserModal from './module/dataBrowserModal.vue'
const fieldsConversion = {
  text: 'input',
  float: 'input',
  date: 'datetime',
  long: 'input',
  boolean: 'select',
  integer: 'input',
  object: 'inputJOSN',
}
// 即时保存示例
export default {
  name: 'JSBCDemo',
  components: {
    dataBrowserModal,
    VJsoneditor,
    vueJsonEditor,
  },
  data() {
    return {
      model: {
        index: 'achievement_index',
        esUrl: 'http://127.0.0.1:9200',
      },
      objectFieldArr: [],
      // 工具栏的按钮配置
      toolbarConfig: {
        // add 新增按钮；remove 删除按钮；clearSelection 清空选择按钮
        btn: [],
        slots: ['prefix', 'suffix'],
      },

      // 是否正在加载
      loading: false,
      // 分页器参数
      pagination: {
        // 当前页码
        current: 1,
        // 每页的条数
        pageSize: 200,
        // 可切换的条数
        pageSizeOptions: ['10', '20', '30', '100', '200'],
        // 数据总数（目前并不知道真实的总数，所以先填写0，在后台查出来后再赋值）
        total: 0,
      },
      // 选择的行
      selectedRows: [],
      // 数据源，控制表格的数据
      dataSource: [],
      // 列配置，控制表格显示的列
      columns: [],
      // 查询url地址
      url: {
        getData: '/es/getData',
        mappings: '/es/getFieldMappings',
        // 模拟保存单行数据（即时保存）
        saveRow: '/es/update',
        delete: '/es/delete',
        // 模拟保存整个表格的数据
        saveAll: '/mock/vxe/immediateSaveAll',
      },
      indeterminate: true,
      checkAll: false,
      checkedList: [],
      plainOptions: ['id'],
    }
  },
  created() {},
  methods: {
    handleSubmit() {
      this.loadFeild()
    },
    // 加载数据
    loadData() {
      // 封装查询条件
      let formData = {
        index: this.model.index,
        esUrl: this.model.esUrl,
        pageNo: this.pagination.current,
        pageSize: this.pagination.pageSize,
      }
      // 调用查询数据接口
      this.loading = true
      getAction(this.url.getData, formData)
        .then((res) => {
          if (res.success) {
            try {
              const result = JSON.parse(res.result)
              this.pagination.total = result.hits.total.value
              console.log(result)
              this.dataSource = result.hits.hits.map((e) => {
                return {
                  id: e._id,
                  index: e._index,
                  score: e._score,

                  ...e._source,
                  ...this.objectFieldArr.reduce((acc, field) => {
                    if (e._source.hasOwnProperty(field)) {
                      acc[field] = JSON.stringify(e._source[field])
                    }
                    return acc
                  }, {}),
                }
              })
              console.log(this.dataSource)
            } catch (e) {
              console.error('JSON 解析错误:', e.message)
            }

            // 后台查询回来的 total，数据总数量
            //     this.pagination.total = res.result.total
            //     // 将查询的数据赋值给 dataSource
            //     this.dataSource = res.result.records
            //     // 重置选择
            //     this.selectedRows = []
            //   } else {
            //     this.$error({ title: '主表查询失败', content: res.message })
          }
        })
        .finally(() => {
          // 这里是无论成功或失败都会执行的方法，在这里关闭loading

          this.loading = false
        })
    },
    loadFeild() {
      let formData = {
        index: this.model.index,
      }
      getAction(this.url.mappings, formData)
        .then((res) => {
          if (res.success) {
            let arr = []
            let columns = res.result.properties
            for (let key in columns) {
              const obj = {
                key: key,
                type: JVXETypes[this.returnType(columns[key].type ? columns[key].type : 'object')],
                title: key,
                width: '600px',
                visible: true,
                // slotName: columns[key].type ? null : key,
                dateFormat: columns[key].type == 'date' ? 'YYYY-MM-DD' : null,
                options:
                  columns[key].type == 'boolean'
                    ? [
                        { title: 'true', value: true },
                        { title: 'false', value: false },
                      ]
                    : null,
              }
              arr.push(obj)
              this.plainOptions.push(key)
              // 此字段是对象, 存入数组 使用
              if (columns[key].properties) {
                this.objectFieldArr.push(key)
              }
            }
            this.columns = arr
            console.log(this.columns)
          }
        })
        .finally(() => {
          // 这里是无论成功或失败都会执行的方法，在这里关闭loading
          this.loadData()
        })
    },
    returnType(type) {
      return fieldsConversion[type]
    },
    // 【整体保存】点击保存按钮时触发的事件
    handleTableSave({ $table, target }) {
      // 校验整个表格
      $table.validate().then((errMap) => {
        // 校验通过
        if (!errMap) {
          // 获取所有数据
          let tableData = target.getTableData()
          console.log('当前保存的数据是：', tableData)
          // 获取新增的数据
          let newData = target.getNewData()
          console.log('-- 新增的数据：', newData)
          // 获取删除的数据
          let deleteData = target.getDeleteData()
          console.log('-- 删除的数据：', deleteData)

          // 【模拟保存】
          this.loading = true
          postAction(this.url.saveAll, tableData)
            .then((res) => {
              if (res.success) {
                this.$message.success(`保存成功！`)
              } else {
                this.$message.warn(`保存失败：` + res.message)
              }
            })
            .finally(() => {
              this.loading = false
            })
        }
      })
    },

    // 触发单元格删除事件
    handleTableRemove(event) {
      // 把 event.deleteRows 传给后台进行删除（注意：这里不会传递前端逻辑新增的数据，因为不需要请求后台删除）
      console.log('待删除的数据: ', event.deleteRows)
      // 也可以只传ID，因为可以根据ID删除
      let deleteIds = event.deleteRows.map((row) => row.id)
      console.log('待删除的数据ids: ', deleteIds)

      // 模拟请求后台删除
      this.loading = true
      window.setTimeout(() => {
        this.loading = false
        this.$message.success('删除成功')
        // 假设后台返回删除成功，必须要调用 confirmRemove() 方法，才会真正在表格里移除（会同时删除选中的逻辑新增的数据）
        event.confirmRemove()
      }, 1000)
    },

    // 单元格编辑完成之后触发的事件
    handleEditClosed(event) {
      let that = this
      let { $table, row, column } = event

      let field = column.property
      let cellValue = row[field]
      // 判断单元格值是否被修改
      if ($table.isUpdateByRow(row, field)) {
        // 校验当前行
        $table.validate(row).then((errMap) => {
          // 校验通过
          if (!errMap) {
            // 【模拟保存】
            let hideLoading = this.$message.loading(`正在保存"${column.title}"`, 0)
            console.log('即时保存数据：', row)
            this.objectFieldArr.forEach((field) => {
              if (row.hasOwnProperty(field) && row[field]) {
                try {
                  row[field] = JSON.parse(row[field])
                } catch (error) {
                  console.error(`解析错误: ${field}`, error)
                  // 在这里你可以决定当解析失败时是否要保留原始的字符串，或者赋予其他的默认值
                }
              }
            })
            putAction(this.url.saveRow, row)
              .then((res) => {
                if (res.success) {
                  this.$message.success(`"${column.title}"保存成功！`)
                  // 局部更新单元格为已保存状态
                  $table.reloadRow(row, null, field)
                } else {
                  this.$message.warn(`"${column.title}"保存失败：` + res.message)
                }
              })
              .finally(() => {
                hideLoading()
                this.loadData()
              })
          }
        })
      }
    },

    // 当分页参数变化时触发的事件
    handlePageChange(event) {
      // 重新赋值
      this.pagination.current = event.current
      this.pagination.pageSize = event.pageSize
      // 查询数据
      this.loadData()
    },

    // 当选择的行变化时触发的事件
    handleSelectRowChange(event) {
      this.selectedRows = event.selectedRows
    },
    handleTableGet() {
      console.log(this.$refs.jvxetable)
    },
    handleAllocationp(e) {
      this.refreshColumn(e)
    },
    onCheckAllChange(e) {
      Object.assign(this, {
        checkedList: e.target.checked ? this.plainOptions : [],
        indeterminate: false,
        checkAll: e.target.checked,
      })
    },
    handleAllocationpSave(e) {
      //   this.refreshColumn(e)
      //   console.log(this.$refs.jvxetable)
    },
    refreshColumn(arr) {
      console.log(arr)
      const columns = this.$refs.jvxetable.getColumns()
      columns.forEach((e) => {
        if (!arr.includes(e.key)) {
          this.$refs.jvxetable.hideColumn(e.key)
        }
      })

      //   this.$refs.jvxetable.refreshColumn()
    },
    handleAdd() {
      this.$refs.modalForm.add()
      this.$refs.modalForm.title = '新增'
      this.$refs.modalForm.disableSubmit = false
    },
    test(e) {
      console.log(e)
    },
    handleTest(e) {
      console.log(e)
    },
  },
}
</script>
  
  <style scoped>
</style>